<template>
	<div class="">
		<div class="button_group mb-3">
			<el-button type="primary" @click="addVis = true" plain size="small" :icon="Plus">添加</el-button>
		</div>
		<div class="body_group">
			<!--     树表格-->
			<el-table :data="page.list" style="width: 100%" :tree-props="{ children: 'children' }" border row-key="id">
				<el-table-column prop="id" label="ID" width="180"></el-table-column>
				<el-table-column prop="meta.title" label="路由标题" width="180"></el-table-column>
				<el-table-column prop="meta.icon" label="路由图标" width="180">
					<template #default="{ row }">
						<el-icon>
							<component :is="ElIcons[row.meta.icon]" />
						</el-icon>
					</template>
				</el-table-column>
				<el-table-column prop="name" label="访问名称" width="180"></el-table-column>
				<el-table-column prop="path" label="访问路径" width="180"></el-table-column>
				<el-table-column prop="component" label="页面路径">
					<template #default="{ row }">
						<span>{{ row.component || "组件不存在" }}</span>
						<!--						<el-button @click="createPageComponent(row.component)">创建</el-button>-->
					</template>
				</el-table-column>

				<el-table-column label="操作" width="180">
					<template #default="{ row }">
						<el-button size="small" @click="handleEdit(row)">编辑</el-button>
						<el-button size="small" @click="handleDelete(row)">删除</el-button>
					</template>
				</el-table-column>
			</el-table>

			<!--   编辑   -->
			<el-dialog title="编辑" :model-value="editVis" draggable @close="editVis = false">
				<el-form :model="editForm" label-width="80px">
					<el-form-item label="路由标题" prop="meta.title" :rules="[{ required: true, message: '请输入路由标题', trigger: 'blur' }]">
						<el-input v-model="editForm.meta.title"></el-input>
					</el-form-item>
					<el-form-item label="路由图标" prop="meta.icon" :rules="[{ required: true, message: '请输入路由图标', trigger: 'blur' }]">
						<el-select-v2 v-model="editForm.meta.icon" :options="componentOptions" placeholder="请选择图标" filterable clearable>
							<template #default="{ item }">
								<div class="flex items-center">
									<el-icon size="18" class="mr-2">
										<component :is="ElIcons[item.value]" />
									</el-icon>
									<span>{{ item.label }}</span>
								</div>
							</template>
						</el-select-v2>
					</el-form-item>
					<el-form-item label="访问路径" prop="path">
						<el-input v-model="editForm.path"></el-input>
					</el-form-item>
					<el-form-item label="页面路径">
						<el-input v-model="editForm.component"></el-input>
					</el-form-item>
				</el-form>
				<template #footer>
					<el-button @click="editVis = false">取 消</el-button>
					<el-button type="primary" @click="updateMenu">确 定</el-button>
				</template>
			</el-dialog>
			<!--    添加  -->
			<el-dialog title="添加" :model-value="addVis" draggable @close="addVis = false">
				<el-form :model="addForm" label-width="80px" :rules="rules" ref="addRef">
					<!--     路由层级      -->
					<el-form-item label="路由层级" prop="parent_id">
						<el-tree-select v-model="addForm.parent_id" :data="addTreeData" :render-after-expand="false" :props="treeProps" check-strictly node-key="id" :expand-on-click-node="false"> </el-tree-select>
					</el-form-item>
					<el-form-item label="路由标题" prop="meta.title" :rules="[{ required: true, message: '请输入路由标题', trigger: 'blur' }]">
						<el-input v-model="addForm.meta.title" placeholder="请输入路由标题"></el-input>
					</el-form-item>
					<el-form-item label="路由图标" prop="meta.icon" :rules="[{ required: true, message: '请输入路由图标', trigger: 'blur' }]">
						<el-select-v2 v-model="addForm.meta.icon" :options="componentOptions" placeholder="请选择图标" filterable clearable>
							<template #default="{ item }">
								<div class="flex items-center">
									<el-icon size="18" class="mr-2">
										<component :is="ElIcons[item.value]" />
									</el-icon>
									<span>{{ item.label }}</span>
								</div>
							</template>
						</el-select-v2>
					</el-form-item>
					<el-form-item label="访问路径" prop="path">
						<el-input v-model="addForm.path" placeholder="请输入访问路径"></el-input>
					</el-form-item>
					<el-form-item label="访问名称" prop="name">
						<el-input v-model="addForm.name" placeholder="请输入访问名称"></el-input>
					</el-form-item>
					<el-form-item label="页面路径" prop="component">
						<el-space fill>
							<component :is="ElAlert" type="info" :closable="true" v-if="buildEnv == 'development'">
								<p>开发环境下,请比对文件位置进行添加</p>
								<p>文件位置: src/views/{{ addForm.component ? addForm.component : "?" }}.vue</p>
							</component>

							<el-select-v2 v-model="addForm.component" :options="pageModulesOptions" placeholder="请选择页面路径" filterable clearable allow-create popper-append-to-body @change="createPageComponent">
								<template #default="{ item }">
									<div class="flex items-center">
										<span class="mr-3">填入名称:[ {{ item.value }} ]</span>
										<span>实际组件位置: [ {{ item.label }} ]</span>
									</div>
								</template>
							</el-select-v2>
						</el-space>
					</el-form-item>
				</el-form>
				<template #footer>
					<el-button @click="addVis = false">取 消</el-button>
					<el-button type="primary" @click="handleAdd">确 定</el-button>
				</template>
			</el-dialog>
		</div>
	</div>
</template>

<script setup>
import { MenuApi } from "@/composables/Api/PermissionApi";
import { getPageComponent } from "@/router/helper";
import * as ElIcons from "@element-plus/icons-vue";
import { Plus } from "@element-plus/icons-vue";
import { ElAlert } from "element-plus";
import encrypt from "@/utils/crypto";
/**
 * Api
 */
const router = useRouter();
const route = useRoute();

const { fetchList, createComponent, deleteMenu, updateMenu, createMenu } = MenuApi();

/**
 * Component Page
 * @type {*}
 */
const componentOptions = ref([]);
for (const key in ElIcons) {
	componentOptions.value.push({
		label: key,
		value: key
	});
}
/**
 * 列表
 * ***************************************************
 */
let page = reactive({
	list: []
});
const fetchTableData = async () => {
	const {
		data: { list }
	} = await fetchList({ title: "", page: "", pageSize: "" });
	page.list = list;
};

/**
 * 编辑
 * ***************************************************
 */
const editVis = ref(false);
let editForm = reactive({});
const handleEdit = row => {
	editForm = row;
	editVis.value = true;
};

/**
 *  添加
 *  *************************************************
 */
const addVis = ref(false);
const addTreeData = ref(null);
const addRef = ref(null);
const treeProps = {
	children: "children",
	label: item => item.meta.title
};
let addForm = reactive({
	meta: {
		icon: undefined
	}
});

const handleAdd = () => {
	addVis.value = true;
	addRef.value.validate().then(() => {
		createMenu(addForm).then(res => {
			fetchTableData();
			addVis.value = false;
		});
	});
};

/**
 * Common
 * ***************************************************
 */

const buildEnv = import.meta.env.MODE;
const pageModules = import.meta.glob("/src/views/**/*.{vue,js}");
const pageModulesOptions = ref([]);
for (const key in pageModules) {
	const exclued = ["APP", "error", "login", "layout"];
	if (exclued.some(item => key.includes(item))) {
		continue;
	}
	// /src/views/permission/Role/index.vue => /permission/Role/index
	pageModulesOptions.value.push({
		label: key,
		value: key.replace(/^\/src\/views\/(.+)\.vue$/, "$1").replace(/\//g, "/")
	});
}
const pageModulesOptionsHasPath = () => {
	return pageModulesOptions.value.some(item => item.value === addForm.component);
};

const rules = reactive({
	meta: {
		title: [{ required: true, message: "请输入路由标题", trigger: ["blur", "change"] }],
		icon: [{ required: true, message: "请输入路由图标", trigger: ["blur", "change"] }]
	},
	parent_id: [{ required: true, message: "请选择父级菜单", trigger: ["blur", "change"] }],
	name: [
		{ required: true, message: "请输入访问名称", trigger: ["blur", "change"] },
		{ pattern: /^[a-zA-Z]+$/, message: "请输入英文", trigger: ["blur", "change"] }
	],
	path: [{ required: true, message: "请输入访问路径", trigger: ["blur", "change"] }],
	component: [
		{
			validator: (rule, value, callback) => {
				if (value) {
					if (getPageComponent(value, pageModules, "boolean")) {
						callback();
					}
					callback();
				} else {
					callback();
				}
			}
		}
	]
});

const createPageComponent = async path => {
	const encryData = {
		showAddVis: true,
		form: "addForm",
		...addForm
	};

	await router.push({ path: router.currentRoute.value.path, query: { data: encrypt.encrypt(JSON.stringify(encryData)) } });
	if (!pageModulesOptionsHasPath(path)) {
		await createComponent({ path });
	}
};

/**
 * 删除
 * **************************************************
 */
const handleDelete = row => {
	const { id } = row;
	if (id) {
		deleteMenu({ id }).then(res => {
			fetchTableData();
		});
	}
};

/**
 * Live
 */

onMounted(async () => {
	await fetchTableData();
	await nextTick();
	addTreeData.value = [
		{
			id: 0,
			meta: {
				title: "顶级菜单"
			}
		},
		...page.list
	];
	// 参数解密
	const { data } = route.query;
	if (data) {
		const resultCrypt = JSON.parse(encrypt.decrypt(data));
		if (resultCrypt.showAddVis) {
			addVis.value = true;
			addForm = reactive(resultCrypt);
			// 用完后清除地址栏参数
			router.replace({ path: route.path });
		}
	}
});
</script>

<style scoped>
div {
	@apply w-full;
}
</style>
